package com.xyrl.common.util;

import com.alibaba.fastjson.JSONObject;
import com.xyrl.common.util.http.HttpClientManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 远程请求连接工具类
 *
 * @author zhongp
 * @version 1.0.1
 * @date 2019-02-26
 */
@Slf4j
public class HttpClientUtil {

    private static String postReq(String url, Map<String, String> paramMap, CloseableHttpClient httpclient)
            throws IOException {
        CloseableHttpResponse response = null;
        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.setConfig(HttpClientManager.requestConfig);
            List<NameValuePair> formparams = setHttpParams(paramMap);
            UrlEncodedFormEntity param = new UrlEncodedFormEntity(formparams, "UTF-8");
            httpPost.setEntity(param);
            response = httpclient.execute(httpPost);
            String httpEntityContent = getHttpEntityContent(response);
            return httpEntityContent;
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            // 释放连接
            try {
                EntityUtils.consume(response.getEntity());
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 封装HTTP POST方法
     *
     * @param
     * @param
     * @return
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String post(String url, Map<String, String> paramMap) throws IOException {
        CloseableHttpClient httpclient = HttpClientManager.getHttpClient();
        return postReq(url, paramMap, httpclient);
    }

    /**
     * 获得响应HTTP实体内容
     *
     * @param response
     * @return
     * @throws IOException
     * @throws java.io.UnsupportedEncodingException
     */
    public static String getHttpEntityContent(HttpResponse response) throws IOException {
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream is = entity.getContent();
            BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String line = br.readLine();
            StringBuilder sb = new StringBuilder();
            while (line != null) {
                sb.append(line + "\n");
                line = br.readLine();
            }
            return sb.toString();
        }
        return "";
    }

    /**
     * 手机端登录
     *
     * @param url 请求的url
     * @throws Exception
     */
    public static String get(String url) throws Exception {
        return get(url, null, null);
    }

    /**
     * 手机端登录
     *
     * @param url 请求的url
     * @throws Exception
     */
    public static String get(String url, Map<String, String> params) throws Exception {
        return get(url, null, params);
    }

    /**
     * 手机端登录
     *
     * @param url 请求的url
     * @throws Exception
     */
    public static String get(String url, Map<String, String> postHeaders, Map<String, String> params) throws Exception {
        CloseableHttpClient httpclient = HttpClientManager.getHttpClient();
        HttpGet get = null;
        HttpClientContext context = HttpClientContext.create();
        try {
            // 创建访问的地址
            URIBuilder uriBuilder = new URIBuilder(url);
            if (params != null) {
                Set<Map.Entry<String, String>> entrySet = params.entrySet();
                for (Map.Entry<String, String> entry : entrySet) {
                    uriBuilder.setParameter(entry.getKey(), entry.getValue());
                }
            }
            log.info("请求的url地址:[{}]", uriBuilder.build().getPath());
            get = new HttpGet(uriBuilder.build());
            get.setConfig(HttpClientManager.requestConfig);
            if (ObjectUtil.isNotEmpty(postHeaders)) {
                for (String key : postHeaders.keySet()) {
                    get.addHeader(key, postHeaders.get(key));
                }
            }
            CloseableHttpResponse response = httpclient.execute(get, context);
            // 执行请求
            String responseEntity = EntityUtils.toString(response.getEntity(), "utf-8");
            // 释放连接
            get.releaseConnection();
            EntityUtils.consume(response.getEntity());
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                log.info("取得请求的状态值：{}", response.getStatusLine().getStatusCode());
                throw new Exception("请求异常");
            }
            return responseEntity;
        } finally {
            if (ObjectUtil.isNotEmpty(get)) {
                get.releaseConnection();
            }
        }
    }

    /**
     * 设置请求参数
     *
     * @param
     * @return
     */
    private static List<NameValuePair> setHttpParams(Map<String, String> paramMap) {
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        Set<Map.Entry<String, String>> set = paramMap.entrySet();
        for (Map.Entry<String, String> entry : set) {
            formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        return formparams;
    }

    /**
     * <b>方法名：</b>：httpPost<br>
     * <b>功能说明：</b>：httpPost请求<br>
     *
     * @param url
     * @return
     * @throws IOException
     * @author <font color='blue'>束文奇</font>
     * @date 2015-11-4 下午6:11:34
     */
    public static JSONObject wxPost(String url) throws IOException {
        return wxPost(url, null);
    }

    /**
     * <b>方法名：</b>：httpPost<br>
     * <b>功能说明：</b>：httpPost请求<br>
     *
     * @param url
     * @param jsonParam
     * @return
     * @throws IOException
     * @author <font color='blue'>束文奇</font>
     * @date 2015-11-4 下午6:11:34
     */
    public static JSONObject wxPost(String url, JSONObject jsonParam) throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        JSONObject jsonResult = null;
        url = URLDecoder.decode(url, "UTF-8");
        HttpPost httpPost = new HttpPost(url);
        try {
            if (ObjectUtil.isEmpty(jsonParam)) {
                jsonParam = new JSONObject();
            }
            StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            CloseableHttpResponse response = httpclient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == 200) {
                String result = "";
                result = EntityUtils.toString(response.getEntity());
                jsonResult = JSONObject.parseObject(result);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            httpclient.close();
        }
        return jsonResult;
    }

    public static JSONObject weChatPost(String url, JSONObject jsonParam) throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        JSONObject jsonResult = null;
        url = URLDecoder.decode(url, "UTF-8");
        HttpPost httpPost = new HttpPost(url);
        try {
            if (ObjectUtil.isEmpty(jsonParam)) {
                jsonParam = new JSONObject();
            }
            StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            CloseableHttpResponse response = httpclient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == 200) {
                String result = "";
                result = EntityUtils.toString(response.getEntity(), "UTF-8");
                jsonResult = JSONObject.parseObject(result);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            httpclient.close();
        }
        return jsonResult;
    }

    public static String weChatPostBinary(String url, JSONObject jsonParam) throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String result = "";
        url = URLDecoder.decode(url, "UTF-8");
        HttpPost httpPost = new HttpPost(url);
        try {
            if (ObjectUtil.isEmpty(jsonParam)) {
                jsonParam = new JSONObject();
            }
            StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            CloseableHttpResponse response = httpclient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == 200) {
                result = EntityUtils.toString(response.getEntity());
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            httpclient.close();
        }
        return result;
    }

}
